package com.rollway.restful.options;

import com.rollway.restful.MethodMetadata;
import com.rollway.restful.utils.Util;
import javafx.util.Pair;
import lombok.Data;
import org.springframework.lang.Nullable;

import java.util.HashMap;
import java.util.function.Function;

@Data
public class CompositeRestfulOptions extends HashMap<String, CompositeRestfulOptions.CompositeRestfulMethodOptions> {

    /**
     * true 有自定义规则
     *
     * @param serviceName
     * @param configKey
     * @param function
     * @param <T>
     * @return
     */
    @Nullable
    public <T> Pair<Boolean, T> getConfig(String serviceName, String configKey, Function<RestfulOptions.Options, T> function) {
        CompositeRestfulMethodOptions methodOptionsComposite = get(serviceName);
        RestfulOptions.Options options = methodOptionsComposite.get(configKey).getOptions();
        T val;
        if (options != null) {
            val = function.apply(options);
            if (val != null) {
                return new Pair<>(true, val);
            }
        }
        options = methodOptionsComposite.get(Util.DEFAULT).getOptions();
        if (options != null) {
            val = function.apply(options);
            if (val != null) {
                return new Pair<>(true, val);
            }
        }
        val = function.apply(get(Util.DEFAULT).get(Util.DEFAULT).getOptions());
        return new Pair<>(false, val);
    }

    @Nullable
    public <T> Pair<Boolean, T> getConfig(MethodMetadata metadata, Function<RestfulOptions.Options, T> function) {
        return getConfig(metadata.getServiceName(), metadata.getMethodKey(), function);
    }

    public RestfulOptions getRestFulOptions(MethodMetadata metadata) {
        return get(metadata.getServiceName()).get(metadata.getMethodKey());
    }


    public static class CompositeRestfulMethodOptions extends HashMap<String, RestfulOptions> {

        @Override
        public RestfulOptions put(String key, RestfulOptions value) {
            RestfulOptions val = super.put(key, value);
            if (Util.DEFAULT.equals(key)) {
                entrySet().stream().filter(e -> !Util.DEFAULT.equals(e.getKey()))
                        .forEach(entry -> {
                            RestfulOptions options = entry.getValue();
                            options.setScheme(val.getScheme());
                            options.setAuthority(val.getAuthority());
                            options.setPrefix(val.getPrefix());
                        });
            }
            return val;
        }
    }
}
